package com.lm.menus;

import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.Expose;
import com.lm.categories.XmlCategoriesParser;
import com.lm.portlet.VideoPlayerPortlet;

/**
 * The {@link XmlMenu} class contains all the Menus available for one video.
 * The {@link XmlMenu} are based on the <b>menu.xml</b> file.
 * This class implements the design pattern Singleton. The methode getInstance() must be used.
 */
public class XmlMenu {
	private static XmlMenu menu = null;
	private List<XmlMenu> listXmlMenus = new ArrayList<XmlMenu>();
	@Expose private String referenceVideo = null;
	@Expose private String nameVideo = null;
	@Expose private int heightVideo = 3;
	@Expose private int widthVideo = 4;
	@Expose private List<XmlKeyFrame> listKeyFrames = new ArrayList<XmlKeyFrame>();
	
	private XmlMenu(){
		XmlCategoriesParser.parse(VideoPlayerPortlet.ADDRESS + "categories.xml"); // Called only one time, when the application start
	}
	
	/**
	 * Get the unique instance of the class {@link XmlMenu}.
	 * @return The unique instance of {@link XmlMenu}.
	 */
	public static XmlMenu getInstance() {
		if (menu == null) {
			menu = new XmlMenu();
		}
		return menu;
	}

	/**
	 * Add one {@link XmlKeyFrame} is the {@link List} <b>listKeyFrames</b>.
	 * @param XmlMenu
	 * 	The {@link XmlKeyFrame} to add in <b>listKeyFrames</b>.
	 */
	public void addKeyFrame(XmlKeyFrame xmlKeyFrame) {
		this.listKeyFrames.add(xmlKeyFrame);
	}
	
	/**
	 * Get the {@link XmlMenu} of the <b>listXmlMenus</b> {@link List}, corresponding to the <b>referenceVideo</b> given in argument.
	 * @return The wanted {@link XmlMenu} or <b>null</b> if it does not exist.
	 */
	public XmlMenu getXmlMenuByRef(String referenceVideo) {
		XmlMenu xmlMenu = null;
		for (XmlMenu xm : menu.listXmlMenus) {
			if (referenceVideo.equals(xm.getReferenceVideo())) {
				xmlMenu = xm;
			}
		}
		if (xmlMenu == null) { // If the wanted XmlMenu does not already exists, we parse his menu.xml file
			xmlMenu = XmlMenuParser.parse(VideoPlayerPortlet.ADDRESS + referenceVideo + ".xml", new XmlMenu());
			menu.listXmlMenus.add(xmlMenu); // It is add to the listXmlMenus list
		}
		return xmlMenu;
	}

	/**
	 * Get the attribute <b>listKeyFrames</b>.
	 * @return The attribute <b>listKeyFrames</b>.
	 */
	public List<XmlKeyFrame> getListKeyFrames() {
		return listKeyFrames;
	}

	/**
	 * Set the attribute <b>listKeyFrames</b>.
	 * @param listKeyFrames
	 * 	The new attribute <b>listKeyFrames</b>.
	 */
	public void setListKeyFrames(List<XmlKeyFrame> listKeyFrames) {
		this.listKeyFrames = listKeyFrames;
	}
	
	/**
	 * Get the attribute <b>referenceVideo</b>.
	 * @return The attribute <b>referenceVideo</b>
	 */
	public String getReferenceVideo() {
		return referenceVideo;
	}
	
	/**
	 * Set the <b>referenceVideo</b> attribute.
	 * @param referenceVideo
	 * 	The new <b>referenceVideo</b> attribute.
	 */
	public void setReferenceVideo(String referenceVideo) {
		this.referenceVideo = referenceVideo;
	}
	
	/**
	 * Set the <b>nameVideo</b> attribute.
	 * @param nameVideo
	 * 	The new <b>nameVideo</b> attribute.
	 */
	public void setNameVideo(String nameVideo) {
		this.nameVideo = nameVideo;
	}
	
	/**
	 * Set the <b>heightVideo</b> attribute.
	 * @param height
	 * 	The new <b>heightVideo</b> attribute.
	 */
	public void setHeightVideo(int heightVideo) {
		this.heightVideo = heightVideo;
	}
	
	/**
	 * Set the <b>widthVideo</b> attribute.
	 * @param height
	 * 	The new <b>widthVideo</b> attribute.
	 */
	public void setWidthVideo(int widthVideo) {
		this.widthVideo = widthVideo;
	}
	
	/**
	 * Return the {@link XmlKeyFrame} corresponding to the <b>referenceMenu</b> given in argument.
	 * The {@link XmlKeyFrame} is transformed in a Json {@link String}.
	 * @param src
	 * 	The <b>idKeyFrame</b> of the wanted KeyFrame.
	 * @return The wanted {@link XmlKeyFrame} or an empty {@link String} (JSON).
	 */
	public String getXmlMenuToJson(String src) {
		XmlKeyFrame xkf = null;
		for (XmlKeyFrame xmlKeyFrame : this.listKeyFrames){
			if (src.equals(xmlKeyFrame.getSrc())) {
				xkf = xmlKeyFrame;
			}
		}
		if (xkf != null) {
			Gson gson = new Gson();
			return gson.toJson(xkf);
		} else {
			return "{}";
		}
	}
	
	/**
	 * Return the {@link List} of all {@link XmlKeyFrame} (idKeyFrame, timestamp and src) corresponding to the <b>referenceVideo</b> given in argument.
	 * The {@link XmlKeyFrame} is transformed in a Json {@link String}.
	 * @param refVideo
	 * 	The <b>refVideo</b> of the wanted XmlMenu.
	 * @return The {@link List} of all {@link XmlKeyFrame} (idKeyFrame, timestamp and src) or an empty {@link String} (JSON).
	 */
	public String getXmlKeyFramesToJson() {
		if (this.referenceVideo != null) {
			Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); // Reade only the attributes with the @Expose annotation
			return gson.toJson(this);
		} else {
			return "{}";
		}
	}
}
